--
-- Author: shineflag
-- Date: 2017-09-08 16:52:00
--
local skynet = require "skynet"
local log = require("log")
local cluster = require "skynet.cluster"

local TAG = "LOGCENTER"

local logpath = "./"  --日志文件路径
local files =  { --所有的日志文件
	-- poker = {    -- poker file name
	-- 	fname = "poker", --日志文件的基础名字
	-- 	fd = 13,    --文件名柄
	-- 	lineno = 1, --文件行

 --    },
} 

--收到fname相关的日志时，转发给 addr1 addr2
local redirect = {
	-- [fname] = {cname1=proxy1, cname2=proxy2}
}

local MAXLINE = 2000000  --200M左右
local MAXFILE = 10000   --同类文件的当天的最大文件数

----[[
	--当前时间 到北京时区  0时的秒数
--]]
local function tomidtime(  )
    local now = os.time() 
    local beiji = now + 8*3600
    local day_sec = beiji % (3600*24)
    local sec2night = 3600*24 - day_sec
    return sec2night
end

--该文件是否存在
local function logexist( filename )
    local f = io.open(filename,"r")
    if f then
        f:close() 
        return true
    else
        return false
    end
end


--获取该类文件当前时期的最大文件号，超过最大则重复写
local function  updatefilenum( file )
	local fname = file.fname
    local time_info = os.date("%Y%m%d",os.time())
    for i = 1, MAXFILE  do
        local filename =  string.format("%s%s_%s_%d.log",logpath,fname,time_info,i)
        if not logexist(filename) then
        	log.d(TAG,"not exits [%s]",filename)
            return i
        end
    end
    return 1
end

--根据文件名创建一个新的日志文件
local function create_log_file( fname )
	local file = files[fname]
	if not file then 
		file = {fname=fname}
		files[fname] = file
	end

    if file.fd and io.type(file.fd) == "file" then
        file.fd:close()
    end

    local time_info = os.date("%Y%m%d",os.time())
    local filenum = updatefilenum( file )
    local filename =  string.format("%s%s_%s_%d.log",logpath,fname,time_info,filenum)
    file.fd = io.open(filename,"w")
    file.lineno = 0
	log.d(TAG,"create log file fd[%s],fname[%s] fnum[%d] filename[%s]", file.fd, file.fname, filenum, filename)

    return file
end


--将日志信息写入文件
local function write_file(file,msg)
    file.fd:write(msg)
    file.fd:write("\n")
    file.fd:flush()
    file.lineno = file.lineno + 1
    if file.lineno >= MAXLINE then
        create_log_file(file.fname)
    end

end

--根据cluster name 和 service name建立一个连接代理
local function connect_cluster(cname, sname)
	local addr = cluster.query(cname, sname)
	local proxy = cluster.proxy(cname, addr)
	log.d(TAG, "cname[%s] sname[%s] addr:%s proxy:%s", cname,sname,addr, proxy)
	return proxy
end

--将消息转发给其它服务
local function rediect_msg(fname,msg)
	if redirect[fname] then 
		for _, addr in pairs(redirect[fname]) do
			skynet.send(addr, "lua", "rlog", fname,msg)
		end
	end
end

--所有文件都会按天分割
local function day_splite_file()

	local timeout = tomidtime() + 1
	for fname,_ in pairs(files) do 
		create_log_file(fname)
	end
	skynet.timeout(timeout * 100,day_splite_file)
end

--]]

CMD = {}


--[[
--	@desc 将字符串记录到文件
--  @param fname 文件名称
--  @param msg  具体的日志信息
]]
function CMD.record(fname,msg)
	log.d(TAG,"record fname[%s] msg[%s]",fname, msg)
	local file = files[fname]
	if not file then
		file = create_log_file(fname)
	end

	write_file(file, msg)
	rediect_msg(fname,msg)
end

--注册转发消息 当有用户注册时会以 rlog 转发给注册的地址
function CMD.regist(fname, cname)
	redirect[fname] = redirect[fname] or {}

	local proxy = connect_cluster(cname, "logagent")
	redirect[fname][cname] = proxy
end


skynet.start(function()
	logpath = skynet.getenv "logpath" or "./"
	day_splite_file()

	skynet.dispatch("lua", function( session,address, cmd,... )
		local f = CMD[cmd]
		if f then
			if session ~= 0 then
		   		skynet.ret(skynet.pack( f(...) ) )
		   	else
		   		f(...)
		   	end 
		else
		    log.e(TAG,string.format("address[%d] call not exist cmd[%s] ",address,cmd) )
	    end
	end)

	local cname = skynet.getenv "cname"
	log.e(TAG,"cluster cname %s start", cname)
	cluster.open(cname)
	cluster.register("logcenter")
end)